package com.z.system.service.impl;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.z.system.model.Dept;
import com.z.system.model.User;
import com.z.system.repository.DeptRepository;
import com.z.system.repository.UserRepository;
import com.z.system.service.DeptService;

/**
 * 部门服务实现类
 */
@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    private DeptRepository deptRepository;

    @Autowired
    private UserRepository userRepository;

    @Override
    public Dept getDeptById(UUID id) {
        return deptRepository.findById(id).orElse(null);
    }

    @Override
    public Dept getDeptByName(String name) {
        return deptRepository.findByName(name);
    }

    @Override
    public Page<Dept> getDepts(Pageable pageable, Map<String, Object> params) {
        // 这里可以根据参数构建查询条件
        // 简化实现，直接返回所有部门的分页结果
        return deptRepository.findAll(pageable);
    }

    @Override
    public List<Dept> getAllDepts() {
        return deptRepository.findAll();
    }

    @Override
    public List<Dept> getDeptTree() {
        List<Dept> allDepts = deptRepository.findAll();
        return buildDeptTree(allDepts, null);
    }

    @Override
    public List<Dept> getChildDepts(UUID parentId) {
        return deptRepository.findByParentIdOrderBySort(parentId);
    }

    @Override
    public Dept saveDept(Dept dept) {
        // 检查部门名称是否已存在
        if (deptRepository.existsByName(dept.getName())) {
            throw new RuntimeException("部门名称已存在");
        }
        // 检查部门编码是否已存在
        if (deptRepository.existsByCode(dept.getCode())) {
            throw new RuntimeException("部门编码已存在");
        }
        // 设置创建时间
        if (dept.getCreateTime() == null) {
            dept.setCreateTime(new Date());
        }
        return deptRepository.save(dept);
    }

    @Override
    public Dept updateDept(Dept dept) {
        Dept existingDept = deptRepository.findById(dept.getId()).orElseThrow(() -> new RuntimeException("部门不存在"));

        // 检查部门名称是否已存在（排除当前部门）
        if (!existingDept.getName().equals(dept.getName()) &&
                deptRepository.existsByName(dept.getName())) {
            throw new RuntimeException("部门名称已存在");
        }
        // 检查部门编码是否已存在（排除当前部门）
        if (!existingDept.getCode().equals(dept.getCode()) &&
                deptRepository.existsByCode(dept.getCode())) {
            throw new RuntimeException("部门编码已存在");
        }

        // 设置更新时间
        dept.setUpdateTime(new Date());

        return deptRepository.save(dept);
    }

    @Override
    public void deleteDept(UUID id) {
        Dept dept = deptRepository.findById(id).orElseThrow(() -> new RuntimeException("部门不存在"));

        // 检查是否有子部门
        if (hasChildDept(id)) {
            throw new RuntimeException("该部门下存在子部门，无法删除");
        }

        // 检查是否有用户
        if (hasUserInDept(id)) {
            throw new RuntimeException("该部门下存在用户，无法删除");
        }

        deptRepository.delete(dept);
    }

    @Override
    public void deleteDepts(Set<UUID> ids) {
        List<Dept> depts = deptRepository.findAllById(ids);
        if (depts.size() != ids.size()) {
            throw new RuntimeException("部分部门不存在");
        }

        // 检查是否有子部门或用户
        for (Dept dept : depts) {
            if (hasChildDept(dept.getId()) || hasUserInDept(dept.getId())) {
                throw new RuntimeException("部门下存在子部门或用户，无法批量删除");
            }
        }

        deptRepository.deleteAll(depts);
    }

    @Override
    public void updateDeptStatus(UUID id, String enabled) {
        Dept dept = deptRepository.findById(id).orElseThrow(() -> new RuntimeException("部门不存在"));
        dept.setStatus(enabled);
        dept.setUpdateTime(new Date());
        deptRepository.save(dept);
    }

    @Override
    public boolean hasChildDept(UUID id) {
        List<Dept> childDepts = deptRepository.findByParentIdOrderBySort(id);
        return childDepts != null && !childDepts.isEmpty();
    }

    @Override
    public boolean hasUserInDept(UUID id) {
        Iterable<User> users = userRepository.findByDeptId(id);
        return users.iterator().hasNext();
    }

    /**
     * 构建部门树形结构（优化版）
     */
    private List<Dept> buildDeptTree(List<Dept> allDepts, UUID parentId) {
        List<Dept> treeDepts = new ArrayList<>();
        
        // 使用Map缓存父部门ID对应的子部门列表，减少循环次数
        Map<UUID, List<Dept>> parentToChildrenMap = new HashMap<>();
        
        // 一次性构建父子关系映射
        for (Dept dept : allDepts) {
            UUID deptParentId = dept.getParentId();
            parentToChildrenMap.computeIfAbsent(deptParentId, k -> new ArrayList<>()).add(dept);
        }
        
        // 获取当前父部门下的子部门
        List<Dept> children = parentToChildrenMap.get(parentId);
        if (children == null) {
            return treeDepts;
        }
        
        // 按sort字段排序
        children.sort(Comparator.comparingInt(Dept::getSort));
        
        // 递归构建子树
        for (Dept dept : children) {
            dept.setChildren(buildDeptTree(allDepts, dept.getId()));
            treeDepts.add(dept);
        }
        
        return treeDepts;
    }

    @Override
    public Map<String, Object> getDeptStatistics() {
        Map<String, Object> statistics = new HashMap<>();
        
        // 获取部门总数
        long totalDepts = deptRepository.count();
        statistics.put("totalDepts", totalDepts);
        
        // 获取启用状态的部门数量
        long enabledDepts = deptRepository.countByStatus("true");
        statistics.put("enabledDepts", enabledDepts);
        
        // 获取禁用状态的部门数量
        long disabledDepts = deptRepository.countByStatus("false");
        statistics.put("disabledDepts", disabledDepts);
        
        // 获取有子部门的部门数量
        long deptsWithChildren = deptRepository.countByHasChildren();
        statistics.put("deptsWithChildren", deptsWithChildren);
        
        // 获取有用户的部门数量
        long deptsWithUsers = deptRepository.countByHasUsers();
        statistics.put("deptsWithUsers", deptsWithUsers);
        
        return statistics;
    }

    @Override
    public List<Dept> searchDeptsByName(String name) {
        if (name == null || name.trim().isEmpty()) {
            return deptRepository.findAll();
        }
        return deptRepository.findByNameContainingIgnoreCase(name);
    }

    @Override
    public Map<UUID, Long> getDeptUserCounts() {
        Map<UUID, Long> userCounts = new HashMap<>();
        
        // 获取所有部门
        List<Dept> allDepts = deptRepository.findAll();
        
        for (Dept dept : allDepts) {
            long userCount = userRepository.countByDeptId(dept.getId());
            userCounts.put(dept.getId(), userCount);
        }
        
        return userCounts;
    }

    @Override
    public List<Dept> getEnabledDepts() {
        return deptRepository.findByStatus("true");
    }
}